<template>
	<!-- #ifdef H5||APP-PLUS -->
	<view class="c-svga" :svgaData="svgaData" :change:svgaData="svga.render" :fun='fun' :change:fun='svga.callPlayer'>
		<div :id='myCanvasId'></div>
	</view>
	<!-- #endif -->
	<!-- #ifdef MP -->
	<view class="c-svga" >
		<canvas class="canvas" :id="myCanvasId" type="2d"></canvas>
	</view>
	<!-- #endif -->
</template>
<script setup>
	/**
	 * c-svga svga组件
	 * @property {String} canvasId 画布id
	 * @property {String} width 图像宽度 默认750rpx 单位rpx/px
	 * @property {String} height 图像高度 默认750rpx 单位rpx/px
	 * @property {String} src svga文件地址
	 * @property {Boolean} autoPlay 是否自动播放 默认true
	 * @property {Number} loops 动画循环次数，默认值为 0，表示无限循环
	 * @property {Boolean} clearsAfterStop 默认值为 true，表示当动画结束时，清空画布
	 * @property {String} fillMode 默认值为 Forward，可选值 Forward / Backward，当 clearsAfterStop 为 false 时，Forward 表示动画会在结束后停留在最后一帧，Backward 则会在动画结束后停留在第一帧。
	 * @property {Boolean} isOnChange 是否开启播放进度监听 默认false false时不触发onFrame onPercentage
	 * @event {Function()} onFinished 监听动画停止播放 loop!=0时生效
	 * @event {Function()} onFrame 监听动画播放至某帧
	 * @event {Function()} onPercentage 监听动画播放至某进度
	 * 组件内方法统一使用 call(funName, args) 调用player实例方法 详见文档
	 * */
	 import uuid from './js/uuid.js'
	 import { reactive,ref,getCurrentInstance, computed } from "vue";
	 let svgaData=ref()
	 const myCanvasId = computed(()=>{
		 if(!props.canvasId){
			 return 'c'+uuid(18)
		 }else{
			return props.canvasId
		 }
	 })
	 const props = defineProps({
			canvasId:{
				type:String
			},
			width:{
				 type:String,
				 default:'750rpx'
			},
			height:{
				 type:String,
				 default:'750rpx'
			},
			src:{
				type:String,
				required:true
			},
			autoPlay:{ //是否自动播放
				type:Boolean,
				default:true
			},
			loops:{ //动画循环次数，默认值为 0，表示无限循环。
				type:Number,
				default:0
			},
			clearsAfterStop:{ //默认值为 true，表示当动画结束时，清空画布。
				type:Boolean,
				default:true
			},
			fillMode:{ //默认值为 Forward，可选值 Forward / Backward，当 clearsAfterStop 为 false 时，Forward 表示动画会在结束后停留在最后一帧，Backward 则会在动画结束后停留在第一帧。
				type:String,
				default:'Forward'
			},
			isOnChange:{
				type:Boolean,
				default:false
			}
		})
	
		svgaData.value = JSON.stringify(Object.assign({myCanvasId:myCanvasId.value},props))
		let fun =ref({})
		const call=(name,args)=>{
			fun.value={name,args}
			// #ifdef MP
			callPlayer(fun.value)
			// #endif
		}
		// #ifdef MP
		import { Parser, Player } from 'svgaplayer-weapp'
		const getContext=()=>{
			return new Promise((resolve) => {
				const {pixelRatio} = uni.getSystemInfoSync()
				uni.createSelectorQuery()
					.in(getCurrentInstance())
					.select(`#${myCanvasId.value}`)
					.fields({ node: true, size: true })
					.exec(res => {
						let {node: canvas, width, height} = res[0]
						resolve({canvas, width, height ,pixelRatio})
					})
			})
		}
		let player=null
		const render=async ()=>{
			const parser = new Parser;
			player = new Player;
			player.loops=props.loops
			player.clearsAfterStop=props.clearsAfterStop
			player.fillMode=props.fillMode
			await player.setCanvas('#'+myCanvasId.value,getCurrentInstance())
			const videoItem = await parser.load(props.src);
			await player.setVideoItem(videoItem);
			if(props.autoPlay){
				player.startAnimation();
			}
			player.onFinished(()=>{ //只有在loop不为0时候触发
				// console.log('动画停止播放时回调');
				emits('onFinished')
			})
			if(props.isOnChange){
				player.onFrame(frame=>{ //动画播放至某帧后回调
					// console.log(frame);
					try{
						emits('onFrame',frame)
					}catch(e){
						//TODO handle the exception
						console.log(e);
					}
				})
				player.onPercentage(percentage=>{ //动画播放至某进度后回调
					// console.log(percentage);
					try{
						emits('onPercentage',percentage)
					}catch(e){
						//TODO handle the exception
						console.log(e);
					}
				})
			}
			
		}
		render()
		const callPlayer=(val)=>{
			if(!val.name)return;
			let {name, args} = val
			console.log(name, args);
			if(Array.isArray(args)){
				player[name](...args)
			}else{
				player[name](args)
			}
		}
		const emits=defineEmits(['onFinished','onFrame','onPercentage'])
		// #endif
		
		defineExpose({call})
</script>

<!-- #ifndef MP -->
<script>
	//renderjs中callMethod方法只能发送到选项式中...
	export default {
		emits:['onFinished','onFrame','onPercentage'],
		methods:{
			receiveRenderData(val){
				// console.log(val);
				this.$emit(val.name,val.val)
			}
		}
	}
</script>
<script src='./js/render.js' lang="renderjs" module='svga'></script>
<!-- #endif -->
<style lang="scss">
	.c-svga{
		width: v-bind(width);
		height: v-bind(height);
		/* #ifndef MP */
		div{
			width: 100%;height: 100%;
		}
		/* #endif */
		
		.canvas{
			width: 100%;height: 100%;
		}
	}
</style>
